#include "unifiedfileinfo.h"
#include <QFileInfo>
#include <QDir>
#include <QImageReader>
#include <QDebug>
#include <QStandardPaths>
#include <QDateTime>
#include <QCryptographicHash>
#include <QImage>
#include <QPixmap>

UnifiedFileInfo::UnifiedFileInfo(const QString& filePath)
    : filePath(filePath)
{
    QFileInfo fileInfo(filePath);
    if (fileInfo.exists()) {
        this->fileName = fileInfo.fileName();
        this->fileType = detectFileType(filePath);
        this->fileSize = fileInfo.size();
        this->lastModified = fileInfo.lastModified();
        this->addedTime = QDateTime::currentDateTime();
        this->fileIdentity = generateFileIdentity();
        this->identityTime = QDateTime::currentDateTime();
    }
}

UnifiedFileInfo::UnifiedFileInfo(const QString& filePath, const QString& fileName, FileType fileType)
    : filePath(filePath)
    , fileName(fileName)
    , fileType(fileType)
    , addedTime(QDateTime::currentDateTime())
    , identityTime(QDateTime::currentDateTime())
{
    QFileInfo fileInfo(filePath);
    if (fileInfo.exists()) {
        this->fileSize = fileInfo.size();
        this->lastModified = fileInfo.lastModified();
        this->fileIdentity = generateFileIdentity();
    }
}

// === 静态工具方法实现 ===

FileType UnifiedFileInfo::detectFileType(const QString& filePath)
{
    QString extension = QFileInfo(filePath).suffix().toLower();
    
    if (extension == "pdf") {
        return FileType::PDF;
    }
    
    // 支持的图片格式
    QStringList imageExtensions = {"jpg", "jpeg", "png", "bmp", "gif", "tiff", "tif", "webp"};
    if (imageExtensions.contains(extension)) {
        return FileType::Image;
    }
    
    return FileType::Unknown;
}

QString UnifiedFileInfo::fileTypeToString(FileType type)
{
    switch (type) {
        case FileType::Image:
            return "image";
        case FileType::PDF:
            return "pdf";
        case FileType::Unknown:
        default:
            return "unknown";
    }
}

FileType UnifiedFileInfo::stringToFileType(const QString& typeString)
{
    QString lower = typeString.toLower();
    if (lower == "image") {
        return FileType::Image;
    } else if (lower == "pdf") {
        return FileType::PDF;
    }
    return FileType::Unknown;
}

int UnifiedFileInfo::layoutModeToInt(LayoutMode mode)
{
    return static_cast<int>(mode);
}

LayoutMode UnifiedFileInfo::intToLayoutMode(int mode)
{
    switch (mode) {
        case 1:
            return LayoutMode::SingleColumn;
        case 2:
            return LayoutMode::TwoColumns;
        case 3:
            return LayoutMode::ThreeColumns;
        default:
            return LayoutMode::SingleColumn;
    }
}

QString UnifiedFileInfo::layoutModeToString(LayoutMode mode)
{
    switch (mode) {
        case LayoutMode::SingleColumn:
            return "单栏";
        case LayoutMode::TwoColumns:
            return "双栏";
        case LayoutMode::ThreeColumns:
            return "三栏";
        default:
            return "未知";
    }
}

int UnifiedFileInfo::pageNumberPositionToInt(PageNumberPosition position)
{
    return static_cast<int>(position);
}

PageNumberPosition UnifiedFileInfo::intToPageNumberPosition(int position)
{
    switch (position) {
        case 1:
            return PageNumberPosition::FooterCenter;
        case 2:
            return PageNumberPosition::FooterRight;
        case 3:
            return PageNumberPosition::HeaderRight;
        default:
            return PageNumberPosition::FooterCenter;
    }
}

QString UnifiedFileInfo::pageNumberPositionToString(PageNumberPosition position)
{
    switch (position) {
        case PageNumberPosition::FooterCenter:
            return "页脚居中";
        case PageNumberPosition::FooterRight:
            return "页脚右侧";
        case PageNumberPosition::HeaderRight:
            return "页眉右侧";
        default:
            return "未知";
    }
}

int UnifiedFileInfo::pageNumberFormatToInt(PageNumberFormat format)
{
    return static_cast<int>(format);
}

PageNumberFormat UnifiedFileInfo::intToPageNumberFormat(int format)
{
    switch (format) {
        case 0:
            return PageNumberFormat::SimpleNumber;
        case 1:
            return PageNumberFormat::WithTotalPages;
        default:
            return PageNumberFormat::SimpleNumber;
    }
}

QString UnifiedFileInfo::pageNumberFormatToString(PageNumberFormat format)
{
    switch (format) {
        case PageNumberFormat::SimpleNumber:
            return "简单数字";
        case PageNumberFormat::WithTotalPages:
            return "带总页数";
        default:
            return "未知";
    }
}

int UnifiedFileInfo::splitStrategyToInt(SplitStrategy strategy)
{
    return static_cast<int>(strategy);
}

SplitStrategy UnifiedFileInfo::intToSplitStrategy(int strategy)
{
    switch (strategy) {
        case 0:
            return SplitStrategy::MergeThenSplit;
        case 1:
            return SplitStrategy::SplitThenMerge;
        default:
            return SplitStrategy::MergeThenSplit;
    }
}

QString UnifiedFileInfo::splitStrategyToString(SplitStrategy strategy)
{
    switch (strategy) {
        case SplitStrategy::MergeThenSplit:
            return "先拼接再分页";
        case SplitStrategy::SplitThenMerge:
            return "先分页再合并";
        default:
            return "未知";
    }
}

QString UnifiedFileInfo::processStatusToString(FileProcessStatus status)
{
    switch (status) {
        case FileProcessStatus::Waiting:
            return "等待中";
        case FileProcessStatus::Processing:
            return "处理中";
        case FileProcessStatus::Completed:
            return "已完成";
        case FileProcessStatus::Error:
            return "错误";
        default:
            return "未知";
    }
}

FileProcessStatus UnifiedFileInfo::stringToProcessStatus(const QString& status)
{
    QString lower = status.toLower();
    if (lower.contains("等待")) {
        return FileProcessStatus::Waiting;
    } else if (lower.contains("处理")) {
        return FileProcessStatus::Processing;
    } else if (lower.contains("完成")) {
        return FileProcessStatus::Completed;
    } else if (lower.contains("错误")) {
        return FileProcessStatus::Error;
    }
    return FileProcessStatus::Waiting;
}

// === 实例方法实现 ===

int UnifiedFileInfo::calculateTotalPages() const
{
    int basePages = pageCount;
    switch (layoutMode) {
        case LayoutMode::SingleColumn:
            return basePages;
        case LayoutMode::TwoColumns:
            return (basePages + 1) / 2;  // 向上取整
        case LayoutMode::ThreeColumns:
            return (basePages + 2) / 3;  // 向上取整
        default:
            return basePages;
    }
}

QString UnifiedFileInfo::generateFileIdentity() const
{
    if (filePath.isEmpty()) {
        return QString();
    }
    
    QString content = QString("%1_%2_%3")
        .arg(filePath)
        .arg(fileName)
        .arg(lastModified.toString(Qt::ISODate));
    
    QCryptographicHash hash(QCryptographicHash::Md5);
    hash.addData(content.toUtf8());
    return hash.result().toHex();
}

QString UnifiedFileInfo::formatFileSize() const
{
    if (fileSize < 1024) {
        return QString("%1 B").arg(fileSize);
    } else if (fileSize < 1024 * 1024) {
        return QString("%1 KB").arg(fileSize / 1024.0, 0, 'f', 1);
    } else if (fileSize < 1024 * 1024 * 1024) {
        return QString("%1 MB").arg(fileSize / (1024.0 * 1024.0), 0, 'f', 1);
    } else {
        return QString("%1 GB").arg(fileSize / (1024.0 * 1024.0 * 1024.0), 0, 'f', 1);
    }
}

bool UnifiedFileInfo::isValid() const
{
    return !filePath.isEmpty() && 
           !fileName.isEmpty() && 
           fileType != FileType::Unknown &&
           QFileInfo(filePath).exists();
}

bool UnifiedFileInfo::needsProcessing() const
{
    return !isProcessed && 
           (processStatus == FileProcessStatus::Waiting || 
            processStatus == FileProcessStatus::Error);
}

bool UnifiedFileInfo::isProcessingComplete() const
{
    return processStatus == FileProcessStatus::Completed && isProcessed;
}

bool UnifiedFileInfo::hasError() const
{
    return processStatus == FileProcessStatus::Error || !errorMessage.isEmpty();
}

void UnifiedFileInfo::resetProcessingState()
{
    isProcessed = false;
    processStatus = FileProcessStatus::Waiting;
    progress = 0;
    statusText = "等待处理";
    errorMessage.clear();
    status = FileStatusIconManager::FileStatus::Queued;
    processedPages.clear();
}

void UnifiedFileInfo::updateProgress(int progress, const QString& statusText)
{
    this->progress = qBound(0, progress, 100);
    this->statusText = statusText;
    this->processStatus = FileProcessStatus::Processing;
    this->status = FileStatusIconManager::FileStatus::Processing;
}

void UnifiedFileInfo::setError(const QString& errorMessage)
{
    this->errorMessage = errorMessage;
    this->processStatus = FileProcessStatus::Error;
    this->status = FileStatusIconManager::FileStatus::Error;
    this->progress = 0;
    this->statusText = "处理失败";
}

void UnifiedFileInfo::setCompleted()
{
    this->isProcessed = true;
    this->processStatus = FileProcessStatus::Completed;
    this->status = FileStatusIconManager::FileStatus::Completed;
    this->progress = 100;
    this->statusText = "处理完成";
    this->errorMessage.clear();
}

void UnifiedFileInfo::setProcessing()
{
    this->processStatus = FileProcessStatus::Processing;
    this->status = FileStatusIconManager::FileStatus::Processing;
    this->statusText = "处理中";
}

QString UnifiedFileInfo::getDisplayName() const
{
    if (!documentTitle.isEmpty()) {
        return documentTitle;
    }
    return fileName;
}

QString UnifiedFileInfo::getFileExtension() const
{
    return QFileInfo(filePath).suffix().toLower();
}

bool UnifiedFileInfo::isImageFile() const
{
    return fileType == FileType::Image;
}

bool UnifiedFileInfo::isPdfFile() const
{
    return fileType == FileType::PDF;
}

bool UnifiedFileInfo::refreshFromDisk()
{
    QFileInfo fileInfo(filePath);
    if (!fileInfo.exists()) {
        return false;
    }
    
    fileName = fileInfo.fileName();
    fileSize = fileInfo.size();
    lastModified = fileInfo.lastModified();
    fileType = detectFileType(filePath);
    
    // 重新生成文件标识
    QString newIdentity = generateFileIdentity();
    if (newIdentity != fileIdentity) {
        fileIdentity = newIdentity;
        identityTime = QDateTime::currentDateTime();
        // 文件已改变，重置处理状态
        resetProcessingState();
    }
    
    return true;
}

bool UnifiedFileInfo::generateThumbnail(const QSize& size)
{
    if (fileType == FileType::Image) {
        QImageReader reader(filePath);
        reader.setScaledSize(size);
        QImage image = reader.read();
        if (!image.isNull()) {
            thumbnail = QPixmap::fromImage(image);
            return true;
        }
    }
    // TODO: 为PDF生成缩略图
    return false;
}

void UnifiedFileInfo::clearProcessedData()
{
    processedPages.clear();
    thumbnail = QPixmap();
}

// === 比较操作符实现 ===

bool UnifiedFileInfo::operator==(const UnifiedFileInfo& other) const
{
    return fileIdentity == other.fileIdentity;
}

bool UnifiedFileInfo::operator!=(const UnifiedFileInfo& other) const
{
    return !(*this == other);
}

bool UnifiedFileInfo::operator<(const UnifiedFileInfo& other) const
{
    // 按添加时间排序
    return addedTime < other.addedTime;
}

// === 序列化支持实现 ===

QString UnifiedFileInfo::toString() const
{
    return QString("UnifiedFileInfo{path='%1', name='%2', type=%3, pages=%4, status=%5}")
        .arg(filePath)
        .arg(fileName)
        .arg(fileTypeToString(fileType))
        .arg(pageCount)
        .arg(processStatusToString(processStatus));
}

QHash<QString, QVariant> UnifiedFileInfo::toVariantMap() const
{
    QHash<QString, QVariant> map;
    map["filePath"] = filePath;
    map["fileName"] = fileName;
    map["fileType"] = static_cast<int>(fileType);
    map["fileSize"] = fileSize;
    map["lastModified"] = lastModified;
    map["addedTime"] = addedTime;
    map["pageCount"] = pageCount;
    map["hasLongPages"] = hasLongPages;
    map["isLongPage"] = isLongPage;
    map["layoutMode"] = static_cast<int>(layoutMode);
    map["enableEnhancement"] = enableEnhancement;
    map["brightnessAdjustment"] = brightnessAdjustment;
    map["contrastAdjustment"] = contrastAdjustment;
    map["splitStrategy"] = static_cast<int>(splitStrategy);
    map["pageNumberPosition"] = static_cast<int>(pageNumberPosition);
    map["pageNumberFormat"] = static_cast<int>(pageNumberFormat);
    map["startingPageNumber"] = startingPageNumber;
    map["generateCoverPage"] = generateCoverPage;
    map["documentTitle"] = documentTitle;
    map["isProcessed"] = isProcessed;
    map["processStatus"] = static_cast<int>(processStatus);
    map["progress"] = progress;
    map["statusText"] = statusText;
    map["errorMessage"] = errorMessage;
    map["status"] = static_cast<int>(status);
    map["fileIdentity"] = fileIdentity;
    map["identityTime"] = identityTime;
    map["cachedPageCount"] = cachedPageCount;
    map["cachedLatestTime"] = cachedLatestTime;
    map["exportStartPageNumber"] = exportStartPageNumber;
    map["tempPdfPath"] = tempPdfPath;

    // === Martin Fowler重构：序列化CachePathInfo ===
    map["cachePathInfo"] = cachePathInfo.toString();

    return map;
}

UnifiedFileInfo UnifiedFileInfo::fromVariantMap(const QHash<QString, QVariant>& map)
{
    UnifiedFileInfo info;
    info.filePath = map["filePath"].toString();
    info.fileName = map["fileName"].toString();
    info.fileType = static_cast<FileType>(map["fileType"].toInt());
    info.fileSize = map["fileSize"].toLongLong();
    info.lastModified = map["lastModified"].toDateTime();
    info.addedTime = map["addedTime"].toDateTime();
    info.pageCount = map["pageCount"].toInt();
    info.hasLongPages = map["hasLongPages"].toBool();
    info.isLongPage = map["isLongPage"].toBool();
    info.layoutMode = static_cast<LayoutMode>(map["layoutMode"].toInt());
    info.enableEnhancement = map["enableEnhancement"].toBool();
    info.brightnessAdjustment = map["brightnessAdjustment"].toInt();
    info.contrastAdjustment = map["contrastAdjustment"].toInt();
    info.splitStrategy = static_cast<SplitStrategy>(map["splitStrategy"].toInt());
    info.pageNumberPosition = static_cast<PageNumberPosition>(map["pageNumberPosition"].toInt());
    info.pageNumberFormat = static_cast<PageNumberFormat>(map["pageNumberFormat"].toInt());
    info.startingPageNumber = map["startingPageNumber"].toInt();
    info.generateCoverPage = map["generateCoverPage"].toBool();
    info.documentTitle = map["documentTitle"].toString();
    info.isProcessed = map["isProcessed"].toBool();
    info.processStatus = static_cast<FileProcessStatus>(map["processStatus"].toInt());
    info.progress = map["progress"].toInt();
    info.statusText = map["statusText"].toString();
    info.errorMessage = map["errorMessage"].toString();
    info.status = static_cast<FileStatusIconManager::FileStatus>(map["status"].toInt());
    info.fileIdentity = map["fileIdentity"].toString();
    info.identityTime = map["identityTime"].toDateTime();
    info.cachedPageCount = map["cachedPageCount"].toInt();
    info.cachedLatestTime = map["cachedLatestTime"].toDateTime();
    info.exportStartPageNumber = map["exportStartPageNumber"].toInt();
    info.tempPdfPath = map["tempPdfPath"].toString();

    // === Martin Fowler重构：反序列化CachePathInfo ===
    if (map.contains("cachePathInfo")) {
        info.cachePathInfo = CachePathInfo::fromString(map["cachePathInfo"].toString());
    }

    return info;
}

QString UnifiedFileInfo::debugString() const
{
    return QString("UnifiedFileInfo Debug:\n"
                   "  Path: %1\n"
                   "  Name: %2\n"
                   "  Type: %3\n"
                   "  Size: %4\n"
                   "  Pages: %5\n"
                   "  Layout: %6\n"
                   "  Status: %7\n"
                   "  Progress: %8%\n"
                   "  Identity: %9\n"
                   "  Added: %10")
        .arg(filePath)
        .arg(fileName)
        .arg(fileTypeToString(fileType))
        .arg(formatFileSize())
        .arg(pageCount)
        .arg(layoutModeToString(layoutMode))
        .arg(processStatusToString(processStatus))
        .arg(progress)
        .arg(fileIdentity)
        .arg(addedTime.toString());
}

// === Martin Fowler重构：缓存路径管理方法实现 ===

QString UnifiedFileInfo::getActualCacheDirectory() const
{
    return cachePathInfo.getActualCacheDirectory();
}

QString UnifiedFileInfo::getFullCacheDirectory() const
{
    return cachePathInfo.getFullCacheDirectory(fileIdentity);
}

QString UnifiedFileInfo::getPageCacheFilePath(int pageIndex) const
{
    return cachePathInfo.getPageCacheFilePath(fileIdentity, pageIndex);
}

QString UnifiedFileInfo::getThumbnailCacheDirectory() const
{
    return cachePathInfo.getThumbnailCacheDirectory(fileIdentity);
}

QString UnifiedFileInfo::getThumbnailCacheFilePath(int thumbnailIndex) const
{
    return cachePathInfo.getThumbnailCacheFilePath(fileIdentity, thumbnailIndex);
}

void UnifiedFileInfo::setActualCacheDirectory(const QString& cacheDirectory)
{
    cachePathInfo.setActualCacheDirectory(cacheDirectory);
}

bool UnifiedFileInfo::cacheDirectoryExists() const
{
    return cachePathInfo.cacheDirectoryExists(fileIdentity);
}

bool UnifiedFileInfo::ensureCacheDirectoryExists() const
{
    return cachePathInfo.ensureCacheDirectoryExists(fileIdentity);
}

bool UnifiedFileInfo::removeCacheDirectory() const
{
    return cachePathInfo.removeCacheDirectory(fileIdentity);
}

bool UnifiedFileInfo::isUsingGlobalCacheConfig() const
{
    return cachePathInfo.isUsingGlobalConfig();
}

void UnifiedFileInfo::updateCachePathToGlobalConfig(const QString& newGlobalCacheDirectory)
{
    cachePathInfo.updateToGlobalConfig(newGlobalCacheDirectory);
}

QString UnifiedFileInfo::getCachePathStatusInfo() const
{
    return cachePathInfo.getStatusInfo(fileIdentity);
}
